
#ifndef	__A_MSG_MANIP_HPP_2010__
#define	__A_MSG_MANIP_HPP_2010__

#include <string>
#include <cstdio>
#include <cstring>

//
// AMsgManip is a class to compose/decompose message string
// 
// Example :
//	  #include "boque/amsgmanip.hpp"
//
//    std::string	msg;
//    int	id = 1234;
//	  std::string   data( "hello, message!" );
//    int  ret = AMsgManip::box( msg, id, data );
//    assert( 0 == strcmp( msg.c_str(), "1234\thello, message!" ) );
//    
//    std::string  data_out;
//    int   id_out = 0;
//    ret = AMsgManip::unbox( msg, id_out, data_out );
//    assert( id == id_out );
//    assert( data == data_out );
//

class	AMsgManip
{

public	:

	/**
	 * @param msg  [out] result message string
	 * @param id   [in]  id to box into message
	 * @param data [in]  data to box into message
	 * 
	 * @return  0 on success
	 */
	static int	box( std::string& msg, int id, const std::string& data )
	{
		char	buf[ 32 ] = {0};
		int		len = snprintf( buf, sizeof(buf) - 1, "%d\t", id );

		msg.reserve( len + data.size() );
		msg.assign( buf, len );
		msg.append( data );

		return	0;
	}

	/**
	 * @param msg   [in]  message string to decompose
	 * @param id    [out] id unboxed from message
	 * @param data  [out] data unboxed from message
	 *
	 * @return  0 on success 
	 * @return -1 on bad format
	 */
	static int unbox( const std::string& msg, int& id, std::string& data )
	{
		const char*  b = msg.c_str();
		const char*  p = strchr( b, '\t' );
		if ( NULL == p ) {
			return -1;
		}
		size_t	id_len = p - b;
		if ( id_len > 16 ) {
			return	-1;
		}

		char	buf[32] = {0};
		strncpy( buf, b, id_len );
		id = atoi( buf );
		
		++p;
		data.assign( p, msg.size() - id_len - 1 );

		return	0;
	}

};	//// class AMsgManip


#endif	//// __A_MSG_MANIP_HPP_2010__

